#include "pluginmanager.h"
#include <QDir>
#include <QCoreApplication>
#include <QPluginLoader>
#include <QFileInfo>
#include <QDebug>

PluginManager::PluginManager(QObject *parent)
    : QObject(parent)
{
    // 设置插件路径为应用程序目录下的plugins子目录
    m_pluginsPath = QCoreApplication::applicationDirPath() + "/plugins";
}

PluginManager::~PluginManager()
{
    unloadPlugins();
}

void PluginManager::loadPlugins()
{
    QDir pluginsDir(m_pluginsPath);
    if (!pluginsDir.exists()) {
        qDebug() << "Plugins directory does not exist:" << m_pluginsPath;
        return;
    }
    
    // 支持多种插件文件扩展名
    QStringList filters;
#ifdef Q_OS_WIN
    filters << "*.dll";
#else
    filters << "*.so" << "*.dylib";
#endif
    
    pluginsDir.setNameFilters(filters);
    
    for (const QString &fileName : pluginsDir.entryList(QDir::Files)) {
        QString absoluteFilePath = pluginsDir.absoluteFilePath(fileName);
        
        // 跳过已加载的插件
        if (isPluginLoaded(absoluteFilePath)) {
            continue;
        }
        
        QPluginLoader *loader = new QPluginLoader(absoluteFilePath, this);
        QObject *plugin = loader->instance();
        
        if (plugin) {
            PluginInfo info;
            info.loader = loader;
            info.instance = plugin;
            info.fileName = absoluteFilePath;
            
            m_plugins[fileName] = info;
            
            qDebug() << "Loaded plugin:" << fileName;
        } else {
            qDebug() << "Failed to load plugin:" << fileName << loader->errorString();
            delete loader;
        }
    }
}

void PluginManager::unloadPlugins()
{
    for (auto it = m_plugins.begin(); it != m_plugins.end(); ++it) {
        if (it.value().loader) {
            it.value().loader->unload();
            delete it.value().loader;
        }
    }
    m_plugins.clear();
}

QStringList PluginManager::loadedPlugins() const
{
    return m_plugins.keys();
}

bool PluginManager::isPluginLoaded(const QString &pluginName) const
{
    return m_plugins.contains(pluginName);
}